package example.login.token;


import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;

import java.nio.charset.StandardCharsets;
import java.security.Key;
import java.util.Date;
import java.util.Scanner;

/**
 * 需要引入相关依赖，原生java引入了5个jar包：jackson-annotations，jackson-core，jackson-databind,jjwt-api，jjwt-impl，jjwt-jackson
 */
public class Main {
    public static void main(String[] args) {
        //模拟登录请求
        User user = HttpGetRequest();

        // 这个密钥必须足够长，不然会报错
        String secretKey = "yourqwqwedsfsdfsfsfgsfasfsdfghtyfytfyduhgfusgfuysgfjygauysdfgtuyasgfuy";

        // 生成token
        String token = createToken(user, secretKey);
        System.out.println("生成token:");
        System.out.println(token);

        // 解析token
        Claims claims = parseToken(token, secretKey);
        System.out.println("解析token:");
        System.out.println(claims);
    }

    /**
     * 模拟http请求
     * @return User
     */
    public static User HttpGetRequest() {
        Scanner scanner = new Scanner(System.in);
        System.out.print("输入账号:");
        String username = scanner.next();
        System.out.print("输入密码:");
        String password = scanner.next();
        return new User(username, password);
    }

    /**
     * 生成token
     * @param user 用户信息
     * @param secretKey 密钥（secret key）用于对token进行签名和验证。签名是为了确保token的完整性和真实性，
     *                  以防止被篡改或伪造。当使用密钥对token进行签名后，可以在接收到token后使用相同的密钥来验证token的有效性和真实性。
     * @return token字符串
     */
    public static String createToken(User user, String secretKey) {
        SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;

        // 生成一个随机密钥
//        Key key = Keys.secretKeyFor(SignatureAlgorithm.HS256);

        // 设置过期时间为1小时
        Date expiration = new Date(System.currentTimeMillis() + 3600000);

        String token = Jwts.builder()
                .setSubject(user.getUsername())
                .setExpiration(expiration)
                .claim("password", user.getPassword())
                .signWith(signatureAlgorithm, secretKey)
                .compact();
        return token;
    }

    /**
     * token解密
     * @param token 加密后的token
     * @param secretKey wt秘钥 此秘钥一定要保留好在服务端, 不能暴露出去, 否则sign就可以被伪造, 如果对接多个客户端建议改造成多个
     * @return claims
     */
    public static Claims parseToken(String token, String secretKey) {
        Claims claims = Jwts.parser()
                .setSigningKey(secretKey)
                .parseClaimsJws(token)
                .getBody();
        return claims;
    }
}
